using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using BrainTechLLC;

namespace Mud.EmlenMudMain
{
    [DataContract]
    [Serializable]
    public class EffectData 
    {
        public EffectData() { }

        private int type = 0;
        private long efftypeflags = (long)EffectType.NONE;
        private ApplyEffect location = ApplyEffect.NONE;
        private int modifier = 0;
        private DateTime dtLastsUntil = DateTime.MinValue;

        /// <summary>
        /// GeneralTypeOfEffect of effect (used to be gsn, general skill/spell number)
        /// </summary>
        public int GeneralTypeOfEffect
        {
            get { return type; }
            set { type = value; }
        }

        /// <summary>
        /// These fields store bitfields that describe special abilities
        /// or skills bestowed upon the character by this effect
        /// </summary>
        public long EffectTypeFlags
        {
            get { return efftypeflags; }
            set { efftypeflags = value; }
        }

        /// <summary>
        /// Where the effect is applied - not properly named, but oh well...
        /// </summary>
        public ApplyEffect ApplyEffectLocation
        {
            get { return location; }
            set { location = value; }
        }

        /// <summary>
        /// Numeric modifier of "location"
        /// </summary>    
        public int ApplyEffectModifierValue
        {
            get { return modifier; }
            set { modifier = value; }
        }

        /// <summary>
        /// How long the effect lasts
        /// </summary>  
        public DateTime EffectLastsUntil
        {
            get { return dtLastsUntil; }
            set { dtLastsUntil = value; }
        }
    }
}

// OLD CODE to PORT:
//void 
//do_coins (CharacterData  chr, string szUserArguments)
//{
//  int coinage;
//  DEFINE_COMMAND ("coins", do_coins, POSITION_DEAD, 100, ALWAYS, "Creates the specified amount of coins.")

//    if (!is_number (szUserArguments) || szUserArguments[0] == '\0')
//    {
//      return;
//    }
//  coinage = atoi (szUserArguments);
//  if (coinage > 0 && coinage < 1000000)
//    create_amount (coinage, chr, NULL, NULL);
//  return;
//}

//void 
//no_spam (CharacterData  chr, string szUserArguments)
//{
//  DEFINE_COMMAND ("nospam", no_spam, POSITION_DEAD, 0, NORMAL, "Toggles between levels of spam.")

//    if (IS_PLAYER (chr))
//    {
//      chr->pcdata->no_spam = 1;
//      send_to_char ("NoSpam mode ENABLED.\n\r", chr);
//      send_to_char ("NOTE: You can toggle through the modes using the SPAM command.\n\r", chr);
//    }
//  return;
//}

//void 
//add_to_aggro_list (CharacterData  chr)
//{
//  CharacterData c;
//  if (IS_SET (chr->special, IS_IN_AGGRO_LIST))
//    return;
//  for (c = aggressiveMobs; c != NULL; c = c->gen_next)
//    {
//      if (c == chr)
//   return;
//    }
//  chr->gen_next = aggressiveMobs;
//  aggressiveMobs = chr;
//  SET_BIT (chr->special, IS_IN_AGGRO_LIST);
//  return;
//}



//void 
//spam (CharacterData  chr, string szUserArguments)
//{
//  DEFINE_COMMAND ("spam", spam, POSITION_DEAD, 0, NORMAL, "Turns on nospam mode.")
//    if (IS_MOB (chr))
//    return;
//  if (chr->pcdata->no_spam == 0)
//    {
//      send_to_char ("Moderate SPAM mode enabled.\n\r", chr);
//      chr->pcdata->no_spam = 2;
//      return;
//    }
//  else if (chr->pcdata->no_spam == 1)
//    {
//      send_to_char ("FULL SPAM mode enabled.\n\r", chr);
//      chr->pcdata->no_spam = 0;
//      return;
//    }
//  else
//    send_to_char ("NO SPAM mode enabled.\n\r", chr);
//  chr->pcdata->no_spam = 1;
//  return;
//}

//int 
//get_race_look (string szUserArguments)
//{
//  int i;
//  for (i = 0; i < RACE_COUNT; i++)
//    {
//      if (!str_prefix (szUserArguments, race_info[i].name))
//   return (1 << i);
//    }
//  if (!str_cmp (szUserArguments, "alien"))
//    return RC_EVILRACE;
//  if (!str_cmp (szUserArguments, evil))
//    return RC_EVILRACE;
//  if (!str_cmp (szUserArguments, good))
//    return RC_GOODRACE;
//  return 0;
//}

///*
//   * Retrieve a character's age.
// */
//int 
//get_age (CharacterData  chr)
//{
//  return 18 + (((chr->pcdata->played / 2) + (((int) (currentTime - chr->pcdata->logon)) / 2)) / 7200) / 4;
//}

///*
//   * Retrieve character's current strength.
// */
//int 
//get_curr_str (CharacterData  chr)
//{
//  int max;
//  int workspace;
//  max = 30;
//  if (IS_MOB (chr))
//    return number_range (15, 29);
//  workspace = chr->pcdata->PermanentStats[StatTypes.Strength] + chr->pcdata->mod_str;
//  if (pow.penalizeEvilInSun && chr->inRoom && IS_EVIL (chr))
//    {
//      if (IN_SUN (chr))
//   workspace -= 2;
//    }
//  return URANGE (3, workspace, max);
//}

///*
//   * Retrieve character's current intelligence.
// */
//int 
//get_curr_int (CharacterData  chr)
//{
//  int max;
//  int i;
//  max = 30;
//  if (IS_MOB (chr))
//    return number_range (15, 27);
//  i = URANGE (3, chr->pcdata->PermanentStats[StatTypes.Intelligence] + chr->pcdata->mod_int, max);
//  if (HAS_HEAD_BRAIN_IMPLANT (chr))
//    i += 2;
//  return i;
//}

///*
//   * Retrieve character's current wisdom.
// */
//int 
//get_curr_wis (CharacterData  chr)
//{
//  int max;
//  max = 30;
//  if (IS_MOB (chr))
//    return number_range (15, 24);
//  else
//    return URANGE (3, chr->pcdata->PermanentStats[StatTypes.Wisdom] + chr->pcdata->mod_wis, max);
//}

///*
//   * Retrieve character's current dexterity.
// */
//int 
//get_curr_dex (CharacterData  chr)
//{
//  int max;
//  int workspace;
//  max = 30;
//  if (IS_MOB (chr))
//    return number_range (15, 24);
//  workspace = chr->pcdata->PermanentStats[StatTypes.Dexterity] + chr->pcdata->mod_dex;
//  if (pow.penalizeEvilInSun && chr->inRoom && IS_EVIL (chr))
//    {
//      if (IN_SUN (chr))
//   workspace -= 3;
//    }
//  return URANGE (3, workspace, max);
//}

//int 
//get_curr_con (CharacterData  chr)
//{
//  int max;
//  max = 30;
//  if (IS_MOB (chr))
//    return number_range (15, 24);
//  else
//    return URANGE (3, chr->pcdata->PermanentStats[StatTypes.Constitution] + chr->pcdata->mod_con, max);
//}

//bool 
//is_name (const string str, string namelist)
//{
//  char name[SML_LENGTH];
//  if (!str_cmp (str, namelist))
//    return TRUE;
//  for (;;)
//    {
//      if (namelist == NULL)
//   return FALSE;
//      if (!str_cmp(str,namelist)) return TRUE;
//      namelist = one_argy (namelist, name);
//      if (name[0] == '\0')
//   return FALSE;
//      if (!str_cmp (str, name))
//   return TRUE;
//    }
//  return FALSE;
//}


//bool is_approx_name (const string str, string namelist)
//{
//  char name[SML_LENGTH];
//  if (!str_cmp (str, namelist))
//    return TRUE;
//  for (;;)
//    {
//      if (namelist == NULL)
//   return FALSE;
//      namelist = one_argy (namelist, name);
//      if (name[0] == '\0')
//   return FALSE;
//      if (!str_cmp (str, name))
//   return TRUE;
//      if (strlen (str) > 1 && !str_prefix (str, name))
//   return TRUE;
//    }
//  return FALSE;
//}



//void 
//affect_modify (CharacterData  chr, AFFECT_DATA * paf, bool fAdd, short flaggy)
//{
//  int mod;
//  mod = paf->modifier;
//  if (fAdd)
//    {
//      SET_BIT (chr->currentlyAffectedBy, paf->efftypeflags);
//      SET_BIT (chr->more_affected_by, paf->bitvector2);
//    }
//  else
//    {
//      REMOVE_BIT (chr->currentlyAffectedBy, paf->efftypeflags);
//      REMOVE_BIT (chr->more_affected_by, paf->bitvector2);
//      mod = 0 - mod;
//    }
//  if (IS_MOB (chr))
//    {
//      switch (paf->location)
//   {
//   default:
//     bug ("Affect_modify: unknown location %d.", paf->location);
//     return;
//   case NONE:
//     break;
//     if (flaggy == 0)
//       {
//   case STR:
//         break;
//   case DEX:
//         break;
//   case INT:
//         break;
//   case WIS:
//         break;
//   case CON:
//         break;
//       }
//     if (flaggy == 0)
//       {
//   case HIT:
//         chr->HPMax += mod;
//         break;
//   case MOVE:
//         chr->MPMax += mod;
//         break;
//       }
//   case AC:
//     chr->naturalArmor += mod;
//     break;
//   case HITROLL:
//     chr->extraHitroll += mod;
//     break;
//   case DAMROLL:
//     chr->damageRoll += mod;
//     break;
//   case SAVING_THROW:
//     if (IS_PLAYER (chr))
//       chr->pcdata->saving_throw += mod;
//     break;
//   case RESIST_SUMMON:
//     if (IS_PLAYER (chr))
//       chr->pcdata->resist_summon += mod;
//     break;
//   case KICK_DAMAGE:
//     if (IS_PLAYER (chr))
//       chr->pcdata->plus_kick += mod;
//     break;
//   case SNEAK:
//     if (IS_PLAYER (chr))
//       chr->pcdata->plus_sneak += mod;
//     break;
//   case HIDE:
//     if (IS_PLAYER (chr))
//       chr->pcdata->plus_hide += mod;
//     break;
//   }
//      return;
//    }
//  switch (paf->location)
//    {
//    default:
//      bug ("Affect_modify: unknown location %d.", paf->location);
//      return;
//    case NONE:
//      break;
//    case STR:
//      if (flaggy != 1)
//   chr->pcdata->mod_str += mod;
//      break;
//    case DEX:
//      if (flaggy != 1)
//   chr->pcdata->mod_dex += mod;
//      break;
//    case INT:
//      if (flaggy != 1)
//   chr->pcdata->mod_int += mod;
//      break;
//    case WIS:
//      if (flaggy != 1)
//   chr->pcdata->mod_wis += mod;
//      break;
//    case CON:
//      if (flaggy != 1)
//   chr->pcdata->mod_con += mod;
//      break;
//    case HIT:
//      if (flaggy != 1)
//   chr->HPMax += mod;
//      break;
//    case MOVE:
//      if (flaggy != 1)
//   chr->MPMax += mod;
//      break;
//    case AC:
//      chr->naturalArmor += mod;
//      break;
//    case HITROLL:
//      chr->extraHitroll += mod;
//      break;
//    case DAMROLL:
//      chr->damageRoll += mod;
//      break;
//    case SAVING_THROW:
//      if (IS_PLAYER (chr))
//   chr->pcdata->saving_throw += mod;
//      break;
//    case RESIST_SUMMON:
//      if (IS_PLAYER (chr))
//   chr->pcdata->resist_summon += mod;
//      break;
//    case KICK_DAMAGE:
//      if (IS_PLAYER (chr))
//   chr->pcdata->plus_kick += mod;
//      break;
//    case SNEAK:
//      if (IS_PLAYER (chr))
//   chr->pcdata->plus_sneak += mod;
//      break;
//    case HIDE:
//      if (IS_PLAYER (chr))
//   chr->pcdata->plus_hide += mod;
//      break;
//    }

//  if (IS_PLAYER (chr))
//    {
//      chr->currentlyAffectedBy |= chr->pcdata->nat_abilities;
//      chr->currentlyAffectedBy |= race_info[chr->pcdata->race].affect_bits;
//      FIXIT(chr)
//    }
//  return;
//}


//void 
//affect_to_char (CharacterData  chr, AFFECT_DATA * paf)
//{
//  AFFECT_DATA *paf_new;
//  if (IS_PLAYER (chr) && (IN_BATTLE (chr) || CHALLENGE (chr) == 10) && paf->type != gsn_sneak)
//    return;
//  if (IS_PLAYER (chr) && (IS_SET (paf->efftypeflags, AFF_POISON) || paf->type == gsn_poison) && race_info[chr->pcdata->race].poison_immunity)
//    {
//      send_to_char ("You are immune to poison; you resist the effect!\n\r", chr);
//      return;
//    }
//  if (IS_PLAYER (chr) && (IS_SET (paf->efftypeflags, AFF_PLAGUE) || paf->type == gsn_plague) && race_info[chr->pcdata->race].plague_immunity)
//    {
//      send_to_char ("You are immune to plague; you resist the effect!\n\r", chr);
//      return;
//    }

//      paf_new = new AFFECT_DATA; //  (sizeof (*paf_new));

//  *paf_new = *paf;
//  paf_new->next = chr->affected;
//  chr->affected = paf_new;
//  affect_modify (chr, paf_new, TRUE, 0);
//  return;
//}


//void 
//affect_remove (CharacterData  chr, AFFECT_DATA * paf)
//{
//  if (chr->affected == NULL)
//    {
//      bug ("Affect_remove: no affect.", 0);
//      return;
//    }
//  affect_modify (chr, paf, FALSE, 0);
//  if (paf == chr->affected)
//    {
//      chr->affected = paf->next;
//    }
//  else
//    {
//      AFFECT_DATA *prev;
//      for (prev = chr->affected; prev != NULL; prev = (!prev->next ? NULL : prev->next))
//   {
//     if (prev->next == paf)
//       {
//         prev->next = paf->next;
//         break;
//       }
//   }
//      if (prev == NULL)
//   {
//     bug ("Affect_remove: can't find paf.", 0);
//     return;
//   }
//    }  
//  delete paf->next;
//  return;
//}

//void 
//strip_all_affects (CharacterData  chr)
//{
//  AFFECT_DATA *paf;
//  AFFECT_DATA *paf_next;
//  for (paf = chr->affected; paf != NULL; paf = paf_next)
//    {
//      paf_next = paf->next;
//      affect_remove (chr, paf);
//    }
//  chr->currentlyAffectedBy = 0;
//  chr->more_affected_by = 0;
//  if (IS_PLAYER (chr))
//    {
//      chr->currentlyAffectedBy |= chr->pcdata->nat_abilities;
//      chr->currentlyAffectedBy |= race_info[chr->pcdata->race].affect_bits;
//    FIXIT(chr)
//    }
//  return;
//}

//void 
//affect_strip_bits (CharacterData  chr, int bits)
//{
//  AFFECT_DATA *paf;
//  AFFECT_DATA *paf_next;
//  for (paf = chr->affected; paf != NULL; paf = paf_next)
//    {
//      if (!paf->next)
//   paf_next = NULL;
//      else
//   paf_next = paf->next;
//      if (IS_SET (paf->efftypeflags, bits))
//   affect_remove (chr, paf);
//    }
//  if (IS_PLAYER (chr))
//    {
//      chr->currentlyAffectedBy |= chr->pcdata->nat_abilities;
//      chr->currentlyAffectedBy |= race_info[chr->pcdata->race].affect_bits;
//      FIXIT(chr)
//    }
//  return;
//}

//void 
//affect_strip (CharacterData  chr, int sn)
//{
//  AFFECT_DATA *paf;
//  AFFECT_DATA *paf_next;
//  if (sn < 0)
//    return;
//  for (paf = chr->affected; paf != NULL; paf = paf_next)
//    {
//      if (!paf->next)
//   paf_next = NULL;
//      else
//   paf_next = paf->next;
//      if (paf->type == sn)
//   affect_remove (chr, paf);
//    }
//  if (IS_PLAYER (chr))
//    {
//      chr->currentlyAffectedBy |= chr->pcdata->nat_abilities;
//      chr->currentlyAffectedBy |= race_info[chr->pcdata->race].affect_bits;
//    FIXIT(chr)
//    }
//  return;
//}


//bool 
//is_affected (CharacterData  chr, int sn)
//{
//  AFFECT_DATA *paf;
//  for (paf = chr->affected; paf != NULL; paf = paf->next)
//    {
//      if (paf->type == sn)
//   return TRUE;
//    }
//  return FALSE;
//}

//bool 
//is_affectedt (CharacterData  chr, int bits)
//{
//  AFFECT_DATA *paf;
//  for (paf = chr->affected; paf != NULL; paf = paf->next)
//    {
//      if (IS_SET (paf->efftypeflags, bits))
//   return TRUE;
//    }
//  return FALSE;
//}


//void 
//affect_join (CharacterData  chr, AFFECT_DATA * paf)
//{
//  AFFECT_DATA *paf_old;
//  bool found;
//  if (paf->type < 0)
//    return;
//  if (IS_PLAYER (chr) && (IN_BATTLE (chr) || CHALLENGE (chr) == 10))
//    return;
//  found = FALSE;
//  for (paf_old = chr->affected; paf_old != NULL; paf_old = paf_old->next)
//    {
//      if (paf_old->type == paf->type)
//   {
//     paf->duration += paf_old->duration;
//     paf->modifier += paf_old->modifier;
//     affect_remove (chr, paf_old);
//     break;
//   }
//    }
//  affect_to_char (chr, paf);
//  return;
//}
